from time import sleep  # 导入time模块中的sleep函数
from threading import Thread,Lock  # 导入threading模块中的Thread类

# 定义账户类
class Account(object):
    def __init__(self):
        self._balance = 0  # 初始化账户余额为0
        self._lock = Lock() # 初始化锁

    # 存款方法
    def deposit(self, money):
        # 先获取锁才能执行后续的代码
        self._lock.acquire()

        try:
            # 计算存款后的余额
            new_balance = self._balance + money
            # 模拟受理存款业务需要0.01秒的时间
            sleep(0.01)
            # 修改账户余额
            self._balance = new_balance
        finally:
            # 在finally中执行释放锁的操作保证正常异常锁都能释放
            self._lock.release()    # 释放锁

    # 属性装饰器，获取账户余额
    @property
    def balance(self):
        return self._balance

# 定义存款线程类
class AddMoneyThread(Thread):
    def __init__(self, account, money):
        super().__init__()  # 调用父类构造函数
        self._account = account  # 被存款的账户对象
        self._money = money  # 存款金额

    # 线程执行的方法
    def run(self):
        self._account.deposit(self._money)  # 调用账户的存款方法

# 定义主函数
def main():
    account = Account()  # 创建账户对象
    threads = []  # 存储线程对象的列表
    # 创建100个存款的线程向同一个账户中存钱
    for _ in range(100):
        t = AddMoneyThread(account, 1)  # 创建存款线程
        threads.append(t)  # 将线程添加到列表
        t.start()  # 启动线程
    # 等所有存款的线程都执行完毕
    for t in threads:
        t.join()  # 等待线程结束
    print('账户余额为: ￥%d元' % account.balance)  # 打印账户余额

# 程序入口
if __name__ == '__main__':
    main()  # 调用主函数